package com.atmilan.quartz.utils.product;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import com.atmilan.quartz.model.dto.im.ImProductItemResDTO;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atmilan.quartz.config.RestTemplateConfig;
import com.atmilan.quartz.constant.Constants;
import com.atmilan.quartz.constant.enums.StockAreaTempEnum;
import com.atmilan.quartz.model.dto.im.ImProductInfoSkuResDTO;
import com.atmilan.quartz.model.dto.im.ImProductPushDTO;
import com.atmilan.quartz.model.dto.im.ImProductResDTO;
import com.atmilan.quartz.model.entity.crmeb.CategoryMatch;
import com.atmilan.quartz.model.entity.crmeb.ProductImage;
import com.atmilan.quartz.model.entity.crmeb.StoreProduct;
import com.atmilan.quartz.model.entity.crmeb.StoreProductAttrValue;
import com.atmilan.quartz.model.entity.crmeb.SystemConfig;
import com.atmilan.quartz.service.IProductImageService;
import com.atmilan.quartz.service.ISystemConfigService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.util.StringUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 拉取商品源数据
 */

@Slf4j
@Service
public class ImProductUtil {

    @Autowired
    private RestTemplateConfig restTemplateConfig;
    @Autowired
    ISystemConfigService systemConfigService;
    @Autowired
    IProductImageService productImageService;

    @Value("${im.appKey}")
    private String imAppKey;
    @Value("${im.appSecret}")
    private String imAppSecret;
    @Value("${im.url.domain}")
    private String imDomainUrl;
    @Value("${im.url.goods}")
    private String imGoodsUrl;
    @Value("${im.url.iterationGoods}")
    private String iterationGoodsUrl;
    @Value("${im.url.token}")
    private String imTokenUrl;
    @Value("${im.url.skus}")
    private String imSkusUrl;
    @Value("${im.url.productSkus}")
    private String imProductSkusUrl;
    @Value("${im.url.category}")
    private String imCategoryUrl;
    @Value("${im.url.brand}")
    private String imBrandUrl;
    @Value("${im.url.productInfo}")
    private String imProductInfoUrl;
    @Value("${im.url.ItemInfo}")
    private String imItemInfoUrl;

    @Value("${imPush.token}")
    private String imPushToken;
    @Value("${imPush.url.domain}")
    private String imPushDomain;
    @Value("${imPush.url.updateProduct}")
    private String imPushUpdateProduct;
    @Value("${imPush.url.updateStock}")
    private String imPushUpdateStock;
    @Value("${imPush.url.productBatch}")
    private String imPushProductBatch;
    @Value("${imPush.url.productEndBatch}")
    private String imPushProductEndBatch;
    @Value("${imPush.url.fullUpdateProduct}")
    private String imPushFullUpdateProduct;

    @Value("${aliyun.oss.oss-url}")
    private String ossUrl;

    /**
     * 查询im分页商品数据
     * @Description:
     * @author daigb
     * @param @param pageNow
     * @param @param pageSize
     * @param @return
     * @param @throws Exception
     * @return InProductResDTO
     * @throws
     */
    public ImProductResDTO selectImPage(Long pageNow, Integer pageSize, SystemConfig systemConfig) throws Exception {
        ImProductResDTO imProductResDTO = null;
        try {
            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("access-token", systemConfig.getValue());
            headers.add("x-forwarded-for", "121.4.132.191");
            JSONObject param = new JSONObject();
            param.put("cursorId", pageNow);
            param.put("limit", pageSize);
            HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(this.imDomainUrl + this.imGoodsUrl, formEntity, String.class);
            ObjectMapper mapper = new ObjectMapper();
            imProductResDTO = mapper.readValue(response.getBody(), ImProductResDTO.class);
            if (HttpStatus.OK != response.getStatusCode()) {
                JSONObject message = JSONObject.parseObject(response.getBody());
//			    String errorMessage = message.getString("error");

                log.info("---------------im分页商品数据异常: {} ---------------", response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return imProductResDTO;
    }

    // 获取Im token
    public SystemConfig getImToken(SystemConfig systemConfigParam) {
        try {
            SystemConfig systemConfig = systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery().eq(SystemConfig::getName, Constants.IM_TOKEN).last("LIMIT 1"));
            // token已被更新
            if (systemConfig.getFormId().intValue() != systemConfigParam.getFormId()) {
                log.info("--------------- IM获取token时发现token已被更新, 直接返回数据库token: {}, {} ---------------", systemConfig.getFormId(), systemConfigParam.getFormId());
                return systemConfig;
            }

            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("x-forwarded-for", "121.4.132.191");
            JSONObject param = new JSONObject();
            param.put("appKey", this.imAppKey);
            param.put("appSecret", this.imAppSecret);
            HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(this.imDomainUrl + this.imTokenUrl, formEntity, String.class);

            log.info("--------------- IM授权获取token返回: {} ---------------", response);
            if (HttpStatus.OK == response.getStatusCode()) {
                String token = JSONObject.parseObject(response.getBody()).getJSONObject("data").getString("access_token");
                systemConfigParam.setValue(token);
                systemConfigParam.setFormId(systemConfigParam.getFormId() + 1);
                systemConfigParam.setUpdateTime(new Date());
                systemConfigService.updateById(systemConfigParam);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalStateException(e);
        }

        return systemConfigParam;
    }

    /**
     * 批量获取improduct商品sku
     * @Description:
     * @author daigb
     * @param @param ids
     * @param @return
     * @param @throws Exception
     * @return InProductResDTO
     * @throws
     */
    public ImProductInfoSkuResDTO getImProductSkus(List<ImProductResDTO.ImProductDTO> imProducts, SystemConfig systemConfig) throws Exception {
        ImProductInfoSkuResDTO imProductInfoSkuResDTO = null;
        try {
            List<Integer> ids = imProducts.stream().map(ImProductResDTO.ImProductDTO::getProductId).collect(Collectors.toList());

            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("access-token", systemConfig.getValue());
            headers.add("x-forwarded-for", "121.4.132.191");
            JSONObject param = new JSONObject();
            param.put("productIds", ids);
            HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(this.imDomainUrl + this.imProductInfoUrl, formEntity, String.class);

            ObjectMapper mapper = new ObjectMapper();
            imProductInfoSkuResDTO = mapper.readValue(response.getBody(), ImProductInfoSkuResDTO.class);
            if (HttpStatus.OK != response.getStatusCode()) {
                JSONObject message = JSONObject.parseObject(response.getBody());
                String errorMessage = message.getString("error");

                log.info("--------------- 批量获取improduct商品sku异常: {} ---------------", errorMessage);
            }
            for (ImProductInfoSkuResDTO.Result result : imProductInfoSkuResDTO.getResults()) {
                List<Integer> itemIds = result.getItemIds();
                if (CollectionUtils.isEmpty(itemIds)) {
                    continue;
                }
                ImProductItemResDTO imItemInfos = new ImProductItemResDTO();
                if (itemIds.size() > 200) {
                    for (int page = 0; page <= itemIds.size() / 200; page++) {
                        if (page > 0 && imItemInfos.getSuccess().equalsIgnoreCase("false")) {
                            break;
                        }
                        int start = page * 200;
                        int end = (page + 1) * 200;
                        if (end > itemIds.size()) {
                            end = itemIds.size();
                        }
                        List<Integer> itemIds1 = itemIds.subList(start, end);
                        ImProductItemResDTO imItemInfos1 = getImItemInfos(itemIds1, systemConfig);
                        if (page == 0) {
                            BeanUtils.copyProperties(imItemInfos1, imItemInfos);
                        } else {
                            imItemInfos.getImProductItemDTOs().addAll(imItemInfos1.getImProductItemDTOs());
                        }
                    }
                } else {
                    imItemInfos = getImItemInfos(result.getItemIds(), systemConfig);
                }
                if (imItemInfos.getSuccess().equalsIgnoreCase("false")) {
                    continue;
                }
                result.setImProductItemDTOs(imItemInfos.getImProductItemDTOs());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return imProductInfoSkuResDTO;
    }

    /**
     * 获取增量数据
     * @param cursorId
     * @param limit
     * @param systemConfig
     * @return
     * @throws Exception
     */
    public ImProductResDTO selectImChangePage(Long cursorId, Integer limit, SystemConfig systemConfig, Long fromChangedTime, Long toChangedTime) throws Exception {
        ImProductResDTO imProductResDTO = null;
        try {
            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("access-token", systemConfig.getValue());
            headers.add("x-forwarded-for", "121.4.132.191");
            JSONObject param = new JSONObject();
            param.put("cursorId", cursorId);
            param.put("limit", limit);
            param.put("fromChangedTime", fromChangedTime);
            param.put("toChangedTime", toChangedTime);
            HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(this.imDomainUrl + this.iterationGoodsUrl, formEntity, String.class);
            ObjectMapper mapper = new ObjectMapper();
            imProductResDTO = mapper.readValue(response.getBody(), ImProductResDTO.class);
            if (HttpStatus.OK != response.getStatusCode()) {
                JSONObject message = JSONObject.parseObject(response.getBody());
//				String errorMessage = message.getString("error");

                log.info("---------------im获取增量数据异常 {} ---------------", message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return imProductResDTO;
    }

    /**
     * 获取批次
     * @author daigb
     * @date:  2022-03-31 16:21
     */
    public String getImPushProductBatch() {
        String batchId = null;
        try {
            RestTemplate restTemplate = new RestTemplateConfig().restTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("Auth-Token", imPushToken);
            HttpEntity<String> formEntity = new HttpEntity<>(null, headers);
            ResponseEntity<String> response = restTemplate.exchange(imPushDomain + imPushProductBatch, HttpMethod.GET, formEntity, String.class);

            System.out.println(response);
            if (HttpStatus.OK != response.getStatusCode()) {
                JSONObject message = JSONObject.parseObject(response.getBody());
                String errorMessage = message.getString("error");

                log.info("--------------- IM商品反向批次获取异常: {} ---------------", errorMessage);
            }
            Boolean b = JSONObject.parseObject(response.getBody()).getBoolean("success");
            if(!b) {
                log.info("--------------- IM商品反向批次获取失败---------------");
            } else {
                batchId = JSONObject.parseObject(response.getBody()).getJSONObject("data").getString("batchId");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return batchId;
    }

    /**
     * 结束批次
     * @author daigb
     * @date:  2022-03-31 16:21
     */
    public void endImPushProductBatch(String batchId, Integer total) {
        try {
            // 批次结束
            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("Auth-Token", imPushToken);
            // 参数
            StringBuilder sb = new StringBuilder();
            sb.append("?batchId=");
            sb.append(batchId);
            sb.append("&total=");
            sb.append(total);

            HttpEntity<JSONArray> formEntity = new HttpEntity<>(null, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(imPushDomain + imPushProductEndBatch + sb, formEntity, String.class);

            if (HttpStatus.OK != response.getStatusCode()) {
                JSONObject message = JSONObject.parseObject(response.getBody());
                String errorMessage = message.getString("error");

                log.info("--------------- IM商品反向结束批次异常: {} ---------------", errorMessage);
            }
            Boolean b = JSONObject.parseObject(response.getBody()).getBoolean("success");
            if(!b) {
                log.info("--------------- IM商品反向结束批次推送失败---------------");
            } else {
                log.info("--------------- IM商品反向结束批次成功---------------");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 构建待推送商品数据
     * @author daigb
     * @date:  2022-04-01 15:20
     */
    public List<ImProductPushDTO> createImGoods(StoreProduct product, List<StoreProductAttrValue> values, CategoryMatch category1, CategoryMatch category2, CategoryMatch category3) throws Exception {
        // 轮播图
        try {
            // sku信息
        	List<ImProductPushDTO.SkuList> skuList = new ArrayList<>();
			for(StoreProductAttrValue value : values) {
			    String[] suks = value.getSuk().split(",");
			    String size = suks[0];
			    if(suks.length > 1) {
			        String[] suk = suks[1].split("=");
			        size = suk[0];
			    }
			
			    ImProductPushDTO.SkuList sku = new ImProductPushDTO.SkuList();
			    sku.setRetailPrice(value.getOtPrice().multiply(new BigDecimal("8")));
			    sku.setSize(size);
			    sku.setStock(value.getStock());
			    sku.setBarcode(value.getSourceSkuId());
			    sku.setCostPrice(value.getCost());
			    sku.setSupplyPrice(value.getPrice());
			
			    skuList.add(sku);
			}

            List<ImProductPushDTO> productDTOs = new ArrayList<>();
            String color = product.getColorCode();
            // 获取色号对应图片
            List<ProductImage> images = productImageService.list(Wrappers.<ProductImage>lambdaQuery()
                    .eq(ProductImage :: getFolderName, product.getKeyword())
                    .eq(ProductImage :: getColor, color)
                    .orderByAsc(ProductImage :: getSort)
            );
            List<String> strImages = images.stream().map(obj -> ossUrl + Constants.UPLOAD_FILE_WAREHOUSE_DIR + obj.getUrl()).collect(Collectors.toList());

            ImProductPushDTO imProductPushDTO = new ImProductPushDTO();
            imProductPushDTO.setBoutiqueId(product.getBarCode() + "-" + color);
            imProductPushDTO.setColorCode(color);
            imProductPushDTO.setSizeCountry("IT");
            imProductPushDTO.setMadeIn("IT");
            imProductPushDTO.setDesignerId(product.getKeyword());
            imProductPushDTO.setBrandName(product.getBrandName());
            imProductPushDTO.setCategory1(null != category1 ? category1.getName() : "");
            imProductPushDTO.setCategory2(null != category2 ? category2.getName() : "");
            imProductPushDTO.setCategory3(null != category3 ? category3.getName() : "");
            imProductPushDTO.setComposition(product.getComposition());
            imProductPushDTO.setImages(strImages);
            imProductPushDTO.setProductDescription(product.getStoreInfo());
            imProductPushDTO.setProductName(product.getStoreName());
            imProductPushDTO.setSeasonCode(StringUtil.isEmpty(product.getSeasonCode()) ? "carryover" : product.getSeasonCode());
            imProductPushDTO.setSkuList(skuList);
            if(product.getTempId() == StockAreaTempEnum.IT.getTempId()) {
            	// 预售时间
                LocalDate startTime = LocalDate.now();
                LocalDate endTime = startTime.plusDays(35);
//            		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                imProductPushDTO.setMinArrivalTime(startTime.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli());
                imProductPushDTO.setMaxArrivalTime(endTime.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli());
            }

            productDTOs.add(imProductPushDTO);

            return productDTOs;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    
    /**
     * 批次更新商品
     * @author daigb
     * @date:  2022-04-01 15:11
     */
    public void batchUpdateImGoods(List<ImProductPushDTO> imProducts, String batchId) throws Exception {
        try {
            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("Auth-Token", imPushToken);
            JSONArray json = JSONArray.parseArray(JSONArray.toJSONString(imProducts));
            HttpEntity<JSONArray> formEntity = new HttpEntity<>(json, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(imPushDomain + imPushFullUpdateProduct + "?batchId=" + batchId, formEntity, String.class);

            if (HttpStatus.OK != response.getStatusCode()) {
                JSONObject message = JSONObject.parseObject(response.getBody());
                String errorMessage = message.getString("message");

                log.info("--------------- IM商品 批量推送异常: {} ---------------", errorMessage);
            }
            Boolean b = JSONObject.parseObject(response.getBody()).getBoolean("success");
            if(!b) {
                log.info("--------------- IM商品批量推送失败: {}---------------", response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 功能描述: 原接口停止维护，批量查询中不再返回商品items，使用此接口替代
     * @Param: [itemIds, systemConfig]
     * @Return: com.atmilan.quartz.model.dto.im.ImProductItemResDTO
     * @Author: wangzh
     * @Date: 2023/7/10 15:01
     */
    public ImProductItemResDTO getImItemInfos(List<Integer> itemIds, SystemConfig systemConfig) throws Exception {
        ImProductItemResDTO imProductItemResDTO = null;
        try {

            RestTemplate restTemplate = restTemplateConfig.restTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("access-token", systemConfig.getValue());
            headers.add("x-forwarded-for", "121.4.132.191");
            JSONObject param = new JSONObject();
            param.put("itemIds", itemIds);
            HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(this.imDomainUrl + this.imItemInfoUrl, formEntity, String.class);

            ObjectMapper mapper = new ObjectMapper();
            imProductItemResDTO = mapper.readValue(response.getBody(), ImProductItemResDTO.class);
            if (HttpStatus.OK != response.getStatusCode()) {
                JSONObject message = JSONObject.parseObject(response.getBody());
                String errorMessage = message.getString("error");

                log.info("--------------- 批量获取imItemInfo商品item异常: {} ---------------", errorMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return imProductItemResDTO;
    }

}
